package start.convert;


import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.FatalBeanException;

public class UtilMethod {
    private static final Logger LOGGER = LoggerFactory.getLogger(UtilMethod.class);

    public UtilMethod() {
    }

    public static void copyProperties(Object source, Object target) throws Exception {
        copyProperties(source, target, (String[])null);
    }

    public static void copyProperties(Object source, Object target, String[] ignoreProperties) {
        Integer addLength = 1;
        String addIgnoreProperty = "serialVersionUID";
        if (ignoreProperties == null) {
            ignoreProperties = new String[addLength];
            ignoreProperties[0] = addIgnoreProperty;
        } else {
            String[] newIgnoreProperties = (String[])Arrays.copyOf(ignoreProperties, ignoreProperties.length + addLength);
            newIgnoreProperties[newIgnoreProperties.length - 1] = "serialVersionUID";
            ignoreProperties = newIgnoreProperties;
        }

        BeanUtils.copyProperties(source, target, ignoreProperties);
    }

    public static void copyPropertiesFromPoToDto(Object source, Object target) throws Exception {
        copyPropertiesFromPoToDto(source, target, (String[])null);
    }

    public static void copyPropertiesFromPoToDto(Object source, Object target, String[] ignoreProperties) throws Exception {
        Integer addLength = 1;
        String addIgnoreProperty = "serialVersionUID";
        if (ignoreProperties == null) {
            ignoreProperties = new String[addLength];
            ignoreProperties[0] = addIgnoreProperty;
        } else {
            String[] newIgnoreProperties = (String[])Arrays.copyOf(ignoreProperties, ignoreProperties.length + addLength);
            newIgnoreProperties[newIgnoreProperties.length - 1] = "serialVersionUID";
            ignoreProperties = newIgnoreProperties;
        }

        BeanUtils.copyProperties(source, target, ignoreProperties);
    }

    public static void setValueWithPropertyName(Object target, String propName, Object value) {
        if (target == null) {
            throw new IllegalArgumentException("target must not be null");
        } else {
            Class clazz = target.getClass();

            try {
                PropertyDescriptor targetPd = new PropertyDescriptor(propName, clazz);
                Method writeMethod = targetPd.getWriteMethod();
                if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
                    writeMethod.setAccessible(true);
                }

                writeMethod.invoke(target, value);
            } catch (Throwable var6) {
                throw new FatalBeanException("Could not set property value", var6);
            }
        }
    }

    public static Object getPropertyValue(Object source, Class<?> clazz, String propertyName) {
        Object value = null;
        PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(clazz, propertyName);
        if (sourcePd != null && sourcePd.getReadMethod() != null) {
            try {
                Method readMethod = sourcePd.getReadMethod();
                if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
                    readMethod.setAccessible(true);
                }

                value = readMethod.invoke(source);
                LOGGER.debug("[UtilMethod getPropertyValue]: " + propertyName + " value is: " + value);
            } catch (Throwable var6) {
                throw new FatalBeanException("Could not get properties value from source", var6);
            }
        }

        return value;
    }

    public static void propertyAssign(Object obj, Map<String, Object> assignFiledMap) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        Iterator var2 = assignFiledMap.keySet().iterator();

        while(var2.hasNext()) {
            String filedName = (String)var2.next();
            PropertyDescriptor pd = getPropertyDescriptor(filedName, obj.getClass());
            if (pd != null) {
                Method write = pd.getWriteMethod();
                write.invoke(obj, assignFiledMap.get(filedName));
            }
        }

    }

    public static Object getPropertyValue(String filedName, Object obj) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        PropertyDescriptor pd = getPropertyDescriptor(filedName, obj.getClass());
        if (filedName == null) {
            if (pd != null) {
                Method rM = pd.getReadMethod();
                return rM.invoke(obj);
            }
        } else {
            String[] split = filedName.split("\\.");
            if (split.length == 2) {
                Object propertyValue = getPropertyValue(split[0], obj);
                return getPropertyValue(split[1], propertyValue);
            }

            if (pd != null) {
                Method rM = pd.getReadMethod();
                return rM.invoke(obj);
            }
        }

        return null;
    }

    public static PropertyDescriptor getPropertyDescriptor(String propertyName, Class<?> clazz) {
        PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(clazz);
        PropertyDescriptor[] var3 = pds;
        int var4 = pds.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            PropertyDescriptor pd = var3[var5];
            if (pd.getName().equals(propertyName)) {
                try {
                    return new PropertyDescriptor(propertyName, clazz);
                } catch (IntrospectionException var8) {
                    var8.printStackTrace();
                }
            }
        }

        return null;
    }

    public static Class getMethodReturnType(Class ObjClass, String propertyName) {
        if (ObjClass != null && propertyName != null && !propertyName.equals("")) {
            Character firstChar = Character.toUpperCase(propertyName.charAt(0));
            propertyName = firstChar + propertyName.substring(1);
            String methodName = "get" + propertyName;

            try {
                Method method = ObjClass.getMethod(methodName);
                return method.getReturnType();
            } catch (Exception var5) {
                return null;
            }
        } else {
            return null;
        }
    }

    public static Class getMethodGenericReturnType(Method method) {
        return getMethodGenericReturnType(method, 0);
    }

    public static Class getMethodGenericReturnType(Method method, int index) {
        Type returnType = method.getGenericReturnType();
        if (returnType instanceof ParameterizedType) {
            ParameterizedType type = (ParameterizedType)returnType;
            Type[] typeArguments = type.getActualTypeArguments();
            if (index < typeArguments.length && index >= 0) {
                return (Class)typeArguments[index];
            } else {
                throw new RuntimeException("你输入的索引" + (index < 0 ? "不能小于0" : "超出了参数的总数"));
            }
        } else {
            return Object.class;
        }
    }
}